<template>
  <view class="container">
    <canvas
        canvas-id="myCanvas"
        id="myCanvas"
        class="canvas"
        @click="handleTouchStart"
    ></canvas>
    <view class="info">
      <text>{{ isHit }}</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isHit: false,
      // 矩形元素参数
      rect: {
        x: 50,      // 中心点X坐标
        y: 60,      // 中心点Y坐标
        width: 100,  // 宽度
        height: 160,  // 高度
        angle: 30,   // 旋转角度(度)
        scale: 0.5,
      },
      // 矩形元素的 按钮参数
      rectBtn: {
        width: 20,  // 宽度
        height: 20,  // 高度
        lastX: 50 - 10,
        lastY: 80 - 10,
      }
    }
  },
  mounted() {
    this.drawCanvas();
  },
  methods: {
    // 绘制Canvas
    drawCanvas() {
      const ctx = uni.createCanvasContext('myCanvas');

      // 清空画布
      ctx.clearRect(0, 0, 300, 300);

      // 保存当前状态
      ctx.save();

      const centerX = this.rect.x + this.rect.width / 2;
      const centerY = this.rect.y + this.rect.height / 2;

      // 移动到矩形中心
      ctx.translate(centerX, centerY);
      // 旋转(转换为弧度)
      ctx.rotate(this.rect.angle * Math.PI / 180);
      // 缩放
      ctx.scale(this.rect.scale, this.rect.scale);

      // 绘制矩形(以中心为原点)
      ctx.fillStyle = '#4CAF50';
      ctx.fillRect(-this.rect.width/2, -this.rect.height/2, this.rect.width, this.rect.height);

      // 恢复状态
      ctx.restore();

      // 旋转附加元素
      ctx.save();
      ctx.translate(centerX, centerY);
      // 旋转(转换为弧度)
      ctx.rotate(this.rect.angle * Math.PI / 180);

      // 缩放
      ctx.scale(this.rect.scale, this.rect.scale);

      // 绘制矩形(以中心为原点)
      ctx.fillStyle = '#a00e61';
      ctx.fillRect( this.rectBtn.lastX, this.rectBtn.lastY, this.rectBtn.width, this.rectBtn.height);
      // 恢复状态
      ctx.restore();

      // 绘制到画布
      ctx.draw();
    },

    // 处理触摸事件
    handleTouchStart(e) {
      console.log('触摸开始', e);
      const query = uni.createSelectorQuery().select('#myCanvas');
      query.boundingClientRect(rect => {
        // 计算点击位置相对于Canvas的坐标
        const x = e.touches[0].clientX - rect.left;
        const y = e.touches[0].clientY - rect.top;

        console.log('点击位置', x, y, e.touches[0]);
        // 检测点击是否在矩形内
        this.isHit = this.checkHit(x, y);

        // 重新绘制以更新状态
        this.drawCanvas();
      }).exec();
    },

    // 检测点击是否在矩形内
    checkHit(x, y) {

      const centerX = this.rect.x + this.rect.width / 2;
      const centerY = this.rect.y + this.rect.height / 2;
      // 1. 坐标逆变换
      const transformedPoint = this.inverseTransform(
          x, y,
          centerX, centerY,
          this.rect.angle * Math.PI / 180,
          this.rect.scale
      );

      console.log({x, y}, '逆变换后的点', transformedPoint);

      // // 2. 检查点是否在原始矩形内
      // const halfWidth = this.rect.width / 2;
      // const halfHeight = this.rect.height / 2;
      //
      // const rectHit = (
      //     transformedPoint.x >= -halfWidth &&
      //     transformedPoint.x <= halfWidth &&
      //     transformedPoint.y >= -halfHeight &&
      //     transformedPoint.y <= halfHeight
      // );

      // 3. 检查点是否在按钮内
      const btnX = this.rectBtn.lastX;
      const btnY = this.rectBtn.lastY;

      const btnHit = (
          transformedPoint.x >= btnX &&
          transformedPoint.x <= btnX + this.rectBtn.width &&
          transformedPoint.y >= btnY &&
          transformedPoint.y <= btnY + this.rectBtn.height
      );

      return {rectHit, btnHit};
    },

    // 坐标逆变换函数
    inverseTransform(x, y, centerX, centerY, angle, scale) {
      // 1. 平移至原点
      let tx = x - centerX;
      let ty = y - centerY;

      // 2. 逆旋转
      const cos = Math.cos(-angle);
      const sin = Math.sin(-angle);
      let rx = tx * cos - ty * sin;
      let ry = tx * sin + ty * cos;

      // 3. 逆缩放
      let sx = rx / scale;
      let sy = ry / scale;

      return {x: sx, y: sy};
    }
  }
}
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

.canvas {
  width: 300px;
  height: 300px;
  border: 1px solid #ccc;
  background-color: #f9f9f9;
}

.info {
  margin-top: 20px;
  font-size: 18px;
}
</style>
